﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

struct VehicleMsg {
  QString ip;
  QString time;
  QString x;
  QString y;
  QString course;
  QString tilt;
  QString roll;
  QString speed;
  QString ox;
  QString oy;
  QString towards;
  QString lspeed;
  QString aspeed;
  QString elec;
  QString status;
  QString res;
} vehicleMsg;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
  ui->setupUi(this);
  ui->pb_stopListen->setEnabled(true);
  ui->pb_stopListen->setEnabled(false);
}

MainWindow::~MainWindow() { delete ui; }

void MainWindow::on_pb_startListen_clicked() {
  chatServer = new ChatServer();
  chatServer->setTcpServer(ui->label_ip->text(), ui->spin_port->text().toInt());

  connect(chatServer, &ChatServer::receiveMsg, this, &MainWindow::receiveMsg,
          Qt::QueuedConnection);

  chatServer->startListen();
  startListenCtrl();
}

void MainWindow::startListenCtrl() {
  ui->pb_startListen->setEnabled(false);
  ui->pb_stopListen->setEnabled(true);
  ui->label_ip->setEnabled(false);
  ui->spin_port->setEnabled(false);
}

void MainWindow::on_pb_stopListen_clicked() {
  chatServer->stopListen();
  stopListenCtrl();

  delete chatServer;
  chatServer = nullptr;
}

void MainWindow::stopListenCtrl() {
  ui->pb_startListen->setEnabled(true);
  ui->pb_stopListen->setEnabled(false);
  ui->label_ip->setEnabled(true);
  ui->spin_port->setEnabled(true);
}

void MainWindow::receiveMsg(const QString &ip, const QString &port,
                            const QByteArray &rawMsg) {
  // 接收字符串数据识别并显示
  recStrMsgShow(ip, port, rawMsg);

  // 接收16进制数据识别并显示
  recHexMsgShow(ip, port, rawMsg);
}

void MainWindow::recStrMsgShow(const QString &ip, const QString &port,
                               const QByteArray &rawMsg) {
  // 接收数据转换为字符串
  QString strMsg = rawMsg;

  // 接收缓冲区显示接收的字符串数据
  ui->text_data_str->append("receive data from " + ip + ":" + port + "\n" +
                            strMsg);

  if (strMsg.mid(0, 3) == "UGV") {
    bool ok;
    
    msgUpdate(strMsg);

    //字符串转化为十进制UTF-8（向下兼容ASCII码），可尝试toLatin1()
    int recRes = vehicleMsg.res.toUtf8().toInt(&ok, 16);
    //qDebug() << allToRes();
    if (recRes == allToRes()) {
      showHSHYJXT();
    } else {
      qDebug() << "HSHYJXT res error";
    }
  }
}

void MainWindow::msgUpdate(QString &strMsg){
    QStringList recMsgList = strMsg.split(",");

    vehicleMsg.ip = recMsgList[1];
    vehicleMsg.time = recMsgList[2];
    vehicleMsg.x = recMsgList[3];
    vehicleMsg.y = recMsgList[4];
    vehicleMsg.course = recMsgList[5];
    vehicleMsg.tilt = recMsgList[6];
    vehicleMsg.roll = recMsgList[7];
    vehicleMsg.speed = recMsgList[8];
    vehicleMsg.ox = recMsgList[9];
    vehicleMsg.oy = recMsgList[10];
    vehicleMsg.towards = recMsgList[11];
    vehicleMsg.lspeed = recMsgList[12];
    vehicleMsg.aspeed = recMsgList[13];
    vehicleMsg.elec = recMsgList[14];
    vehicleMsg.status = recMsgList[15].split("*")[0];
    vehicleMsg.res = recMsgList[15].split("*")[1];
}

int MainWindow::allToRes() {
  int res = 0;

  res ^= divToRes(vehicleMsg.ip);
  res ^= divToRes(vehicleMsg.time);
  res ^= divToRes(vehicleMsg.x);
  res ^= divToRes(vehicleMsg.y);
  res ^= divToRes(vehicleMsg.course);
  res ^= divToRes(vehicleMsg.tilt);
  res ^= divToRes(vehicleMsg.roll);
  res ^= divToRes(vehicleMsg.speed);
  res ^= divToRes(vehicleMsg.ox);
  res ^= divToRes(vehicleMsg.oy);
  res ^= divToRes(vehicleMsg.towards);
  res ^= divToRes(vehicleMsg.lspeed);
  res ^= divToRes(vehicleMsg.aspeed);
  res ^= divToRes(vehicleMsg.elec);
  res ^= divToRes(vehicleMsg.status);

  return res;
}

int MainWindow::divToRes(QString &str) {
  bool ok;
  int data;
  int res = 0;

  QByteArray hexMsg = str.toUtf8().toHex();
  for (int i = 0; i < hexMsg.size() / 2; i++) {
    data = hexMsg.mid(i * 2, 2).toInt(&ok, 16);
    res ^= data;
  }

  return res;
}

void MainWindow::showHSHYJXT() {
  ui->label_car_ip->setText(vehicleMsg.ip);
  ui->label_car_time->setText(vehicleMsg.time);
  ui->label_car_x->setText(vehicleMsg.x);
  ui->label_car_y->setText(vehicleMsg.y);
  ui->label_car_course->setText(vehicleMsg.course);
  ui->label_car_tilt->setText(vehicleMsg.tilt);
  ui->label_car_roll->setText(vehicleMsg.roll);
  ui->label_car_speed->setText(vehicleMsg.speed);
  ui->label_car_ox->setText(vehicleMsg.ox);
  ui->label_car_oy->setText(vehicleMsg.oy);
  ui->label_car_towards->setText(vehicleMsg.towards);
  ui->label_car_lspeed->setText(vehicleMsg.lspeed);
  ui->label_car_aspeed->setText(vehicleMsg.aspeed);
  ui->label_car_elec->setText(vehicleMsg.elec);
  ui->label_car_status->setText(vehicleMsg.status);
}

void MainWindow::recHexMsgShow(const QString &ip, const QString &port,
                               const QByteArray &rawMsg) {
  // 接收数据转换为16进制
  QByteArray hexMsg = rawMsg.toHex();
  // 16进制数转换为字符串
  QString recHexMsg = hexMsg;

  // 接收缓冲区显示接收的16进制数据
  ui->text_data_hex->append("receive data from " + ip + ":" + port + "\n" +
                            recHexMsg);

  if (hexMsg.mid(6, 2) == "01") {
    // 中心回复数据
    chatServerReply();

    // 接收数据处理并显示
    showNU(hexMsg.mid(8, 8), hexMsg.mid(18, 8), hexMsg.mid(26, 8));

    return;
  }
}

void MainWindow::chatServerReply() {
  QByteArray array;
  array.append(char(0x39));
  array.append(char(0x30));
  array.append(char(0x04));
  array.append(char(0x05));
  array.append(char(0xDB));
  array.append(char(0x59));
  array.append(char(0x2F));
  array.append(char(0x0D));
  array.append(char(0x01));
  array.append(char(0x01));
  array.append(char(0xF7));
  array.append(char(0x84));

  chatServer->sendMsg(array);
}

void MainWindow::showNU(QString id, QString realTimeRate,
                        QString cumulativeRate) {
  bool ok;
  // big-endian order to small-endian order
  QString id_0 = id.mid(0, 2);
  QString id_1 = id.mid(2, 2);
  QString id_2 = id.mid(4, 2);
  QString id_3 = id.mid(6, 2);
  uint id_int_0 = id_0.toInt(&ok, 16);
  uint id_int_1 = id_1.toInt(&ok, 16);
  uint id_int_2 = id_2.toInt(&ok, 16);
  uint id_int_3 = id_3.toInt(&ok, 16);
  int id_int = (id_int_3 << 24) + (id_int_2 << 16) + (id_int_1 << 8) + id_int_0;
  // QTableWidgetItem *itemDeviceID1 =
  //     new QTableWidgetItem(QString::number(id_int));
  // qDebug() << itemDeviceID1;
  ui->label_device->setText(QString::number(id_int));
  QString realTimeRate_0 = realTimeRate.mid(0, 2);
  QString realTimeRate_1 = realTimeRate.mid(2, 2);
  QString realTimeRate_2 = realTimeRate.mid(4, 2);
  QString realTimeRate_3 = realTimeRate.mid(6, 2);
  uint realTimeRate_int_0 = realTimeRate_0.toInt(&ok, 16);
  uint realTimeRate_int_1 = realTimeRate_1.toInt(&ok, 16);
  uint realTimeRate_int_2 = realTimeRate_2.toInt(&ok, 16);
  uint realTimeRate_int_3 = realTimeRate_3.toInt(&ok, 16);
  int realTimeRate_int = (realTimeRate_int_3 << 24) +
                         (realTimeRate_int_2 << 16) +
                         (realTimeRate_int_1 << 8) + realTimeRate_int_0;
  // QString RealTimeDoseRate1 = "01020304";
  // QString CumulativeDoseRate1 = "01020304";
  // QTableWidgetItem *itemRealTimeDoseRate1 =
  //     new QTableWidgetItem(QString::number(realTimeRate_int));
  ui->label_actual->setText(QString::number(realTimeRate_int));

  QString cumulativeRate_0 = cumulativeRate.mid(0, 2);
  QString cumulativeRate_1 = cumulativeRate.mid(2, 2);
  QString cumulativeRate_2 = cumulativeRate.mid(4, 2);
  QString cumulativeRate_3 = cumulativeRate.mid(6, 2);
  uint cumulativeRate_int_0 = cumulativeRate_0.toInt(&ok, 16);
  uint cumulativeRate_int_1 = cumulativeRate_1.toInt(&ok, 16);
  uint cumulativeRate_int_2 = cumulativeRate_2.toInt(&ok, 16);
  uint cumulativeRate_int_3 = cumulativeRate_3.toInt(&ok, 16);
  int cumulativeRate_int = (cumulativeRate_int_3 << 24) +
                           (cumulativeRate_int_2 << 16) +
                           (cumulativeRate_int_1 << 8) + cumulativeRate_int_0;
  // QTableWidgetItem *itemCumulativeDoseRate1 =
  //     new QTableWidgetItem(QString::number(cumulativeRate_int));
  // ui->tableWidget_nu->setItem(rowNo, 0, itemDeviceID1);
  // ui->tableWidget_nu->setItem(rowNo, 1, itemRealTimeDoseRate1);
  // ui->tableWidget_nu->setItem(rowNo, 2, itemCumulativeDoseRate1);
  ui->label_cumulative->setText(QString::number(cumulativeRate_int));
}
